""" cleanup.py

This module provides the cron-initiated cleanup routine for the AppEngine
InFlightXt application.

   Copyright 2011 Bravo369.org

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

author = mmeade@google.com
"""

# General imports
import logging
import time

# Application imports
from api import position
from api import sessions

# Framework imports
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine import runtime



def minutes(val):
  return 60.0 * val


def hours(val):
  return 60.0 * minutes(val)


def days(val):
  return 24.0 * hours(val)


def weeks(val):
  return 7.0 * days(val)


def months(val):
  return 4 * weeks(val)


class CleanupHandler(webapp.RequestHandler):
  """Cleanup handler class."""

  _MAX_AGE = months(3)

  def __init__(self, *args, **kwargs):
    super(CleanupHandler, self).__init__(*args, **kwargs)
    self.endTime = time.time() + 25

  def get(self):
    """Implement the GET handler."""
    self.deleteSessions()

  def isAlmostTimeout(self):
    """Determine if the request is about to timeout.

    Returns:
      True if the request is within 5 second of timing out, False otherwise.
    """
    return time.time() >= self.endTime

  def deleteSessions(self):
    """Delete sessions."""
    sessions_ = sessions.Session.all()#, {'start_time <': time.time()})
    sessions_.filter('start_time <', time.time() - self._MAX_AGE)
    end_time = time.time() + 25  # end before 30 second timeout
    for session in sessions_.fetch(1000):
      if self.isAlmostTimeout():
        break
      elif session.save:
        continue
      logging.info(
          'Starting to remove positions for session %s',
          session.id_key
          )

      self.deletePositions(session.id_key)
      logging.info(
          'Removed all positions for session %s, removing session',
          session.id_key
          )

      session.delete()

  def deletePositions(self, session):
    """Delete positions associated with a session."""
    positions_ = position.Position.all()
    positions_.filter('session =', session)
    for position_ in positions_.fetch(1000):
      if self.isAlmostTimeout():
        return
      position_.delete()


application = webapp.WSGIApplication(
    [('/cleanup\.html', CleanupHandler)], debug=True)


def main():
  run_wsgi_app(application)


if __name__ == '__main__':
  main()
